package com.temp.filter;

import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 创建一个自定义的 AuthenticationFilter
 */
public class CustomAuthenticationFilter extends FormAuthenticationFilter {

    @Override
    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
        // 1. 放行所有OPTIONS请求和匿名接口
        if (isPreflightRequest(request) || isAnonRequest(request)) {
            return true;
        }
        // 2. 非匿名接口才检查认证
        return super.isAccessAllowed(request, response, mappedValue);
    }

    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
        // 3. 仅当明确是未认证访问需认证接口时返回401
        if (!isAnonRequest(request)) {
            sendUnauthorizedResponse(response);
            return false;
        }
        // 4. 匿名接口的异常交给Spring处理
        return true;
    }

    private boolean isAnonRequest(ServletRequest request) {
        // 检查该路径是否在Shiro的匿名规则中（需动态获取）
        return AnonPathChecker.isAnonPath(((HttpServletRequest) request).getRequestURI());
    }

    private boolean isPreflightRequest(ServletRequest request) {
        HttpServletRequest req = (HttpServletRequest) request;
        return "OPTIONS".equalsIgnoreCase(req.getMethod());
    }

    private void sendUnauthorizedResponse(ServletResponse response) throws IOException {
        HttpServletResponse httpResp = (HttpServletResponse) response;
        httpResp.setContentType("application/json;charset=UTF-8");
        httpResp.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        httpResp.getWriter().write("{\"code\":401,\"msg\":\"apiMsg.\"unverified\"}");
    }
}
